<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        div {
            height: 200px;
            background: skyblue;
        }
    </style>
</head>
<body>
    <div></div>
    <button>Stop</button>
    <script>
        let count = 0;
        const container = document.querySelector('div');
        function getUserAction() {
            container.innerHTML = count++;
        }
        let debounceFn = debounce(getUserAction, 3000, true);
        container.onmousemove = debounceFn;
        document.querySelector('button').onclick = function() {
            debounceFn.cancel();
        }
        // function debounce(fn, n) {
        //     let time = null;
        //     return function() {
        //         let context = this;
        //         let args = arguments;
        //         clearInterval(time);
        //         time = setTimeout(() => {
        //             fn.apply(context, args);
        //         }, n)
        //     }
        // }
        // debounce 防抖 事件触发n秒后执行，n秒内重新触发事件以新事件时间为准
        function debounce(fn, n, immediate) {
            let time = null;
            let func = function() {
                let context = this, args = arguments;
                if(time) {
                    clearInterval(time);
                }
                if(immediate) {
                    let callNow = !time;
                    time = setTimeout(function() {
                        time = null;
                    }, n);
                    if(callNow) {
                        fn.apply(context, args);
                    }
                }else{
                    time = setTimeout(() => {
                        fn.apply(context, args);
                    }, n)
                }
            }
            func.cancel = function() {
                clearTimeout(time);
                time = null;
            }
            return func;
        }
    </script>
</body>
</html>